<?php
declare (strict_types = 1);

namespace app\admin\controller;
use think\App;
use think\facade\Db;
use think\facade\Request;
use upload\Storage;
use app\admin\model\Setting as SettingModel;
use app\common\enum\file\Storage as StorageEnum;
use think\response\Json;
/**
 * 上传
 * Class Upload
 * @package app\store\controller
 */
class Upload extends Controller
{
    private $engine;
    private $storage;
    private array $fileinfo;
    /**
     * 构造方法
     * @param App $app
     */
    public function __construct(App $app)
    {
        parent::__construct($app);
        // 获取上传引擎参数(例如支付证书这种只能上传到本地的文件需传入该参数)
        $engine = Request::param('engine', '');
        // 获取上传设置
        $setting = SettingModel::getItem('storage');
        // 设置默认上传引擎
        if($engine == ''){
            $engine = $setting['default'];
        }
        $this->engine = $engine;
        // 获取上传引擎配置
        // 本地上传引擎配置domain
        if($engine == StorageEnum::LOCAL){
            $config = ['domain' => Request::domain()];
        }else{
            $config = (array)$setting['engine'][$engine];
        }
        // 实例化上传引擎
        $this->storage = new Storage($engine, $config);
        try {
            // 设置上传文件名
            $this->storage->setUploadFile('file');
            // 获取上传文件信息
            $this->fileinfo = $this->storage->getFileInfo();
            // 设置上传路径
            $this->storage->setPath('admin/'.$this->admin['admin_user_id'], $this->fileinfo['md5'].'.'.$this->fileinfo['extension']);
        } catch (\Throwable $th) {
            return $this->renderError('上传失败');
        }
    }
    /**
     * 上传图片
     * @return Json
     */
    public function img(): Json
    {
        if(!in_array($this->fileinfo['extension'],['jpg','jpeg','png','gif','bmp'])){
            return $this->renderError('文件类型错误');
        }
        if(substr($this->fileinfo['mime'],0,5) != 'image'){
            return $this->renderError('文件类型错误');
        }
        if(filesize($this->fileinfo['path_name'])/1024/1024 > 10){
            return $this->renderError('文件大小不能超过10M');
        }
        $info = $this->uploadfile();
        return json([
            'message' => '上传成功',
            'code' => config('status.success'),
            'id' => $info['id'],
            'name' => $info['name'],
            'status' => $info['status'],
            'url' => $info['url']
        ]);
    }
    /**
     * 上传文件
     * @return Json
     */
    public function file(): Json
    {
        if(!in_array($this->fileinfo['extension'],['pem','crt','pdf'])){
            return $this->renderError('文件类型错误');
        }
        if(filesize($this->fileinfo['path_name'])/1024/1024 > 10){
            return $this->renderError('文件大小不能超过10M');
        }
        $info = $this->uploadfile();
        return json([
            'message' => '上传成功',
            'code' => config('status.success'),
            'id' => $info['id'],
            'name' => $info['name'],
            'status' => $info['status'],
            'url' => $info['url']
        ]);
    }
    /**
     * 上传并入库
     * @return Array
     */
    private function uploadfile(): Array
    {
        // 检查数据库中是否已存在该文件
        $info = Db::name('upload')->where(['type'=>'admin','user_id'=>$this->admin['admin_user_id'],'md5'=>$this->fileinfo['md5']])->find();
        // 如果不存在，则上传文件并入库
        if($info == null){
            $res = $this->storage->upload();
            if(!is_array($res)){
                return $this->renderError($res);
            }
            $filename = $this->fileinfo['file_name'];
            $id = Db::name('upload')->insertGetId([
                'type'        => 'admin',
                'user_id'     => $this->admin['admin_user_id'],
                'storage'     => $this->engine,
                'url'         => $res['path'],
                'filename'    => $filename,
                'filetype'    => $this->fileinfo['extension'],
                'filesize'    => filesize($this->fileinfo['path_name']),
                'mimetype'    => $this->fileinfo['mime'],
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s'),
                'md5'         => $this->fileinfo['md5']
            ]);
            // $id = 0;
        // 如果存在，则返回数据库中的文件信息
        }else{
            $id = $info['id'];
            $filename = $info['filename'];
            $engine = $info['storage'];
            $domain = $this->fileinfo['domain'];
            $res = [
                'path' => $info['url'],
                'url'  => $domain .($this->engine==StorageEnum::LOCAL?'':'/'). $info['url']
            ];
            // 更新时间戳
            Db::name('upload')->where(['type'=>'admin','user_id'=>$this->admin['admin_user_id'],'md5'=>$this->fileinfo['md5']])->update([
                'update_time' => date('Y-m-d H:i:s')
            ]);
        }
        // 返回ant-design-vue的Upload组件需要的数据格式
        return [
            'id'     => $id,
            'name'   => $filename,
            'status' => 'done',
            'url'    => $res['url']
        ];
    }
}
